/**
 * @author Halon
 */
 
 

function Logger(par)
{
    this.name = par
};

Logger.prototype.log = function(method,mesg)
{
   alert('[INFO ' + this.name +'] '+ method +': ' + mesg);
}

 /**
 * @author Halon
 */

function GSMSingleton()
{
    this.logger = new Logger('GSM');
    this.scenes = new Array();
}
GSMSingleton.prototype.show = function(sgm)
{
    for( var s in this.scenes)
        this.scenes[s].deactivate();
    sgm.activate();
}
GSMSingleton.prototype.get = function(sgm)
{
    for( var s in this.scenes)
        if (s == sgm)
            return this.scenes[s];
    this.logger.log('Returning new Scene Manager');
    var ss = new SceneGroupManager();
    this.scenes[sgm] = ss;
    return ss;
}

function SceneGroupManager() {
this.logger = new Logger('SGM');
this.logger.log('ctor', 'creating new SGM');
this.masterScenes = new Array();
this.scenes = new Array();
this.active = null;

};
SceneGroupManager.prototype.addScene = function(scene)
{
    this.logger.log('s', 'Adding scene ' + scene);
    $.sfScene.show(scene);
    $.sfScene.hide(scene);
    for (var s in this.scenes)
        if (s === scene)
            return;
    this.scenes.push(scene);
    this.active = this.scenes[0];
}


SceneGroupManager.prototype.addMasterScene = function(scene)
{
    this.logger.log('s','Adding master scene ' + scene);
    $.sfScene.show(scene);
    $.sfScene.hide(scene);
    for (var s in this.masterScenes)
        if (s === scene)
            return;
    this.masterScenes.push(scene);
}

SceneGroupManager.prototype.activate = function()
{
    this.logger.log('s','activating');
    for(var s in this.masterScenes)
        $.sfScene.show(this.masterScenes[s]);
    $.sfScene.show(this.active);
}
SceneGroupManager.prototype.deactivate = function()
{
    this.logger.log('s','deactivating');
    for(var s in this.masterScenes)
        $.sfScene.hide(this.masterScenes[s]);
    $.sfScene.hide(this.active);
}


SceneGroupManager.prototype.showScene = function(scene)
{
    this.logger.log('s','showing ' + scene);
    $.sfScene.hide(this.active);
    this.active = scene;
    $.sfScene.show(this.active);
}

SceneGroupManager.prototype.show = function(id)
{
    this.logger.log('s','showing scene with id: ' + id);
    $.sfScene.hide(this.active);
    this.active = this.scenes[id];
    $.sfScene.show(this.active);
}



var GSM = new GSMSingleton();






function BtnClb()
{
    this.logger = new Logger('BtnClb');
    this.onActivate = function (){};
    this.onDeactivate = function (){ return true;};
    this.onBtnClicked = function (){};
}

function SettingsTypeBtnClb(scn)
{
    this.scene = scn;
}

SettingsTypeBtnClb.prototype = new BtnClb();
SettingsTypeBtnClb.prototype.onActivate = function()
{
    this.logger.log('onActivate', 'Btn '+ this.scene);
    GSM.get('ProfileEditor').showScene(this.scene);
}

SettingsTypeBtnClb.prototype.onBtnClicked = function()
{
    this.logger.log('onBtnClicked', 'Btn '+ this.scene);
    return {order : $.sfKey.DOWN, command: $.sfKey.ENTER};
}









function UserControl() {
    this.container = null;
    this.active = false;
}
UserControl.prototype.getContainer = function()
{
    return this.contianer;
}
UserControl.prototype.forceFocus = function()
{
    if (this.active)
        return;
    var res = this.container.forceFocus(this);
    if (!res)
        alert('Cant focus object!');
    return res;
}




UserControl.prototype.handleInput = function(key) {
    return {order : key};
}

UserControl.prototype.activate = function(){
    this.active = true;
}
UserControl.prototype.deactivate = function(){
    this.active = false;
    return true;
}
    


function FuzzyUserControl(name,dec,lab,inc)
{
    this.logger = new Logger('FuzzyUC');
    this.name = name;
    this.inc = inc;
    this.dec = dec;
    this.lab = lab;
    this.value = 50;
}

FuzzyUserControl.prototype = new UserControl();

FuzzyUserControl.prototype.handleInput = function(key) {
    if (!this.active)
        this.logger.log('handleInput','Control is not active');
    switch(key)
    {
        case $.sfKey.LEFT:
            this.value--;
            break;
         case $.sfKey.RIGHT:
            this.value++;
            break;
         case $.sfKey.ENTER:
            return false;
         default:
            return {order : key};
    }
    if (this.value < 0)
        this.value = 0;
    if (this.value > 100)
        this.value = 100;
     this.lab.sfLabel({text:this.value});
     return false;
}
FuzzyUserControl.prototype.activate = function(){
    this.inc.sfButton('focus');
    this.dec.sfButton('focus');
    this.active = true;
}
FuzzyUserControl.prototype.deactivate = function(){
    this.inc.sfButton('blur');
    this.dec.sfButton('blur');
    this.active = false;
    return true;
}




function ButtonUserControl(obj, callb)
{
    this.obj = obj;
    if (callb != null)
        this.callb = callb;
    else
        this.callb = new BtnClb();
}
ButtonUserControl.prototype = new UserControl();
ButtonUserControl.prototype.activate = function ()
{
    this.active = true;
    this.callb.onActivate();
    this.obj.sfButton('focus');
}
ButtonUserControl.prototype.deactivate = function()
{
    this.active = false;
    this.obj.sfButton('blur');
    return this.callb.onDeactivate();
}
ButtonUserControl.prototype.handleInput = function(key)
{
    if ($.sfKey.ENTER == key)
    {
        return this.callb.onBtnClicked();
    }
    return {order : key};
}





function ListboxUserControl(lb,callb)
{
    this.obj = lb;
    this.callb = callb;
    this.logger = new Logger('ListBox');
}

ListboxUserControl.prototype = new UserControl();
ListboxUserControl.prototype.activate = function()
{
    this.logger.log('activate',this);
    this.obj.sfList('focus');
    this.active = true;
}
ListboxUserControl.prototype.deactivate = function()
{
    this.logger.log('deactivate',this);
    this.obj.sfList('blur');
    this.active = false;
}


ListboxUserControl.prototype.handleInput = function(key)
{
    this.logger.log('handleInput',key);
    switch(key)
    {
        case $.sfKey.UP:
        //case $.sfKey.RIGHT:
            this.obj.sfList('prev');
            break;
        case $.sfKey.DOWN:
        //case $.sfKey.LEFT:
            this.obj.sfList('next');
            break;
        case $.sfKey.ENTER:
            if (this.callb != null)
                return this.callb(this.obj.sfList('getIndex'));
            else
                return false;
        default:
            return {order : key};
    }
    return false;
    
}




//FIX: 
var GlobalContainer = new Array();
/*GlobalContainer.forceFocus = function(obj)
{
    var cont = this.containers.pop();
    if (cont != null
        if (!cont.deactivate())
            return false;
    this.containers.push(obj);
    obj.activate();
    return true;
}*/
  
function UserControlGroup(name,width,height)
{
    this.name = name;
    this.logger = new Logger(name);
    this.logger.log('ctor','creating new ucg grid (RxC) '+height+'x'+width);
    this.focusStack = new Array();
    this.objects = new Array();
    this.objects.length = width;
    for (i = 0 ; i < height; ++i)
    {
        this.objects[i] = new Array();
        this.objects[i].length = width;
    }
    this.width = width;
    this.height = height;
    this.activeRow = 0;
    this.activeCol = 0;
    this.wrap = true;
    this.useFocus = false;
    this.focusUsed = false;
    this.tmpObjRow = 0;
    this.tmpObjCol = 0;
    this.curObj = null;
    this.container = GlobalContainer;
}
UserControlGroup.prototype = new UserControl();

UserControlGroup.prototype._getObject = function(obj)
{
    for (var i = 0 ; i < this.objects.length ; ++i)
        for (var j = 0 ; j < this.objects[i].length ; ++j)
            if (this.objects[i][j] == obj)
            {
                this.tmpObjRow = i;
                this.tmpObjCol = j;
                return true;
            }
    this.tmpObjRow = -1;
    this.tmpObjCol = -1;
    return false;
}
UserControlGroup.prototype._setTempAsActive = function()
{
     this.activeRow = this.tmpObjRow;
     this.activeCol = this.tmpObjCol;
     this.curObj = this.objects[this.activeRow][this.activeCol];
}


UserControlGroup.prototype.wrapFocus = function(bool)
{
    this.wrap = bool;
}
UserControlGroup.prototype.activate = function(obj)
{
    if (this._getObject(obj))
    {
        if (this.active)
        {
            if (this.curObj != null && this.curObj != obj)
                if (this.curObj.deactivate())
                {
                    this._setTempAsActive();
                    this.curObj.activate();
                }
        }
        else
        {
            this._setTempAsActive();
        }
    }
    else
        alert('Cant find object to activate');
}   


UserControlGroup.prototype.activate = function()
{
    this.logger.log('activate',this);
    if (this.active)
        return;
    this.active = true;
    if (this.curObj != null && this.useFocus == false)
        this.curObj.activate();
}


UserControlGroup.prototype.deactivate = function(obj)
{
    this.logger.log('deactivate child',obj);
    if (this.active)
    {
        if (this.useFocus)
            if (this.curObj != null)
                this.curObj.deactivate();
        else
        {
            alert('Cant deactivate object. Container cant take focus!');
            return false;
        }
    }
    return true;
}

UserControlGroup.prototype.deactivate = function()
{
    this.logger.log('deactivate',this);
    if (this.active)
    {
        if (this.curObj.deactivate())
        {
            this.active = false;
            return true;
        }
        return false;
    }
    return true;
}

UserControlGroup.prototype.forceFocus = function(obj)
{
    if (this.active)
    {
        if (this.curObj != null && obj != this.curObj)
            if (this.curObj.deactivate())
            {
                this.curObj = obj;
                if (this._getObject(obj))
                   this._setTempAsActive();
                else
                    return false;
                return true;
            }
            return false;
    }
    else
    {
        this.container.forceFocus(this);
        if (this.active)
            this.curObject.activate();
        return true;
    }
}

UserControlGroup.prototype.registerObject = function(object,row,col)
{
    this.logger.log('registerObject',object);
    if (this.objects[row][col] != null)
        alert('Object already registered in [' + row +']['+col+']');
    this.objects[row][col] = object;
    object.container = this;
    if (row == 0 && col == 0)
        this.curObj = object;
}
  

UserControlGroup.prototype.handleInput = function(key)
{
    this.logger.log('handleInput',key);
    var hiResult = false;
    if (this.curObj != null && this.curObj.active)
    {
        this.logger.log('handleInput','child is active. Calling curObj.handleInput');
        hiResult = this.curObj.handleInput(key);
        
        if (hiResult === false)
            return false;
        this.logger.log('handleInput','child command: '+ hiResult.command);
        this.logger.log('handleInput','child order: '+ hiResult.order);
        if (hiResult.command == $.sfKey.ENTER)
        {
            this.logger.log('handleInput','pushing child onto focus stack');
            this.focusStack.push(this.curObj);
        }
        key = hiResult.order;
    }
    switch (key)
    {
        case $.sfKey.LEFT:
            this.activeCol--;
            if (this.activeCol < 0)
                if (this.wrap)
                    this.activeCol = this.width-1;
                else
                    this.activeCol = 0;
            break;
        case $.sfKey.RIGHT:
            this.activeCol++;
            this.logger.log('handleInput', 'setting col ' + this.activeCol +' of ' + this.width);
            if (this.activeCol >= this.width)
                if (this.wrap)
                    this.activeCol = 0;
                else
                    this.activeCol = this.width-1;
            break;
        case $.sfKey.UP:
             this.activeRow--;
            if (this.activeRow < 0)
                if (this.wrap)
                    this.activeRow = this.height-1;
                else
                    this.activeRow = 0;
            break;
        case $.sfKey.DOWN:
            this.activeRow++;
            this.logger.log('handleInput', 'setting row ' + this.activeRow  +' of ' + this.height);
            if (this.activeRow >= this.height)
                if (this.wrap)
                    this.activeRow = 0;
                else
                    this.activeRow = this.height-1;
            break;
        case $.sfKey.ENTER:
            if (this.curObj != null)
                this.focusStack.push(this.curObj);
            break;
        case $.sfKey.RETURN:
            if (this.focusStack.length == 0 && this.useFocus == false)
            {
                this.logger.log('handleInput','stack empty, returning focus');
                var res = {order : $.sfKey.RETURN};
                return res;
            }
            this.logger.log('handleInput','poping child from focus stack');
            var prev = this.focusStack.pop();
            
            this._getObject(prev);
            this.curObj.deactivate();
            this._setTempAsActive();
            this.curObj.activate();
            return false;
        default:
            return false;
    }
    this.logger.log('handleInput','activateing [' + this.activeRow + '][' + this.activeCol +']');
    if (this.curObj != null)
        this.curObj.deactivate();
    this.curObj = this.objects[this.activeRow][this.activeCol];
    if (this.curObj != null)
        this.curObj.activate();
    else
        this.logger.log('handleInput','Cant activate - curObj is null');
    return false;
}
















function profileListCallback(ind)
{
    alert('Profile ' + ind + ' selected');
    return {order : $.sfKey.RIGHT, command : $.sfKey.ENTER};
}


function printObject(obj)
{
  alert('Printing object:');
  var out = '';
  for (var p in obj)
  {
    out += p + ': ' + obj[p] + '\n';
  }
  alert(out);
}





function SceneScene1(options) {
	this.options = options;
}

SceneScene1.prototype.initialize = function () {
	alert("SceneScene1.initialize()");
	// this function will be called only once when the scene manager show this scene first time
	// initialize the scene controls and styles, and initialize your variables here 
	// scene HTML and CSS will be loaded before this function is called
    

    if (GlobalContainer[0] == null)
        GlobalContainer[0] = new UserControlGroup('main UCG',2,1);
    this.container = GlobalContainer[0];
    this.initialized = false;
    
}




SceneScene1.prototype.handleShow = function () {
	alert("SceneScene1.handleShow()");
    
}

SceneScene1.prototype.handleHide = function () {
	alert("SceneScene1.handleHide()");
	// this function will be called when the scene manager hide this scene  
}

SceneScene1.prototype.handleFocus = function () {
	alert("SceneScene1.handleFocus()");
	// this function will be called when the scene manager focus this scene
}

SceneScene1.prototype.handleBlur = function () {
	alert("SceneScene1.handleBlur()");
	// this function will be called when the scene manager move focus to another scene from this scene
}

SceneScene1.prototype.handleKeyDown = function (keyCode) {
	alert("SceneScene1.handleKeyDown(" + keyCode + ")");
    if (this.initialized == false)
    {
        alert('Initializing environment');
        this.initialized = true;
        
        this.pe = GSM.get('ProfileEditor');
        
        this.pe.addMasterScene('Scene2');
        this.pe.addMasterScene('Scene3');
        this.pe.addScene('Scene4');
        this.pe.addScene('Scene5');
        GSM.show(this.pe);
        
    }
    else
    if(this.container != null)
        this.container.handleInput(keyCode);
}
